﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Globalization;
using Autofac;
using Autofac.Core;
using Cloak.Globalization;
using Cloak.Mvvm.Navigation;

namespace Cloak.Autofac.Navigation
{
	/// <summary>
	/// Parses parameters used during resolution of view models
	/// </summary>
	public static class PageModelParameterParser
	{
		/// <summary>
		/// Parses the specified set of parameters into Autofac parameters
		/// </summary>
		/// <param name="reference">The page model reference which defines the parameters to parse</param>
		/// <param name="parameters">The parameter values specified during resolution of a view model</param>
		/// <returns>A set of Autofac parameters to use during resolution of the specified view model</returns>
		public static IEnumerable<Parameter> ParseParameters(this PageModelReference reference, IDictionary<string, string> parameters)
		{
			Contract.Requires(reference != null);
			Contract.Requires(parameters != null);

			return ParseParametersCore(reference, parameters);
		}

		private static IEnumerable<Parameter> ParseParametersCore(PageModelReference reference, IDictionary<string, string> parameters)
		{
			foreach(var pageModelParameter in reference.Parameters)
			{
				string value;

				if(!parameters.TryGetValue(pageModelParameter.QueryStringKey, out value))
				{
					throw new ArgumentException(Resources.QueryStringKeyNotSpecified.FormatInvariant(pageModelParameter.QueryStringKey), "parameters");
				}

				yield return CreateAutofacParameter(pageModelParameter, value);
			}
		}

		private static Parameter CreateAutofacParameter(PageModelParameter pageModelParameter, string value)
		{
			return new NamedParameter(pageModelParameter.Name, ConvertValue(value, pageModelParameter.Type));
		}

		private static object ConvertValue(string value, Type type)
		{
			return Convert.ChangeType(value, type, CultureInfo.InvariantCulture);
		}
	}
}